import * as fs from 'fs';
import {ConfigLoader} from '../loader';
import {PagesJsonHelper} from "../helper";
import {Logger} from 'vite';
import {PagesOptions} from "../types";

/**
 * 预加载配置项定义
 */
export interface PreloadConfigItem {
  /**
   * 配置名称（对应pages.json中的字段）
   */
  name: keyof PagesOptions;
  /**
   * 自定义比较函数，用于判断配置是否发生变化
   */
  compareFunction?: (oldConfig: any, newConfig: any) => boolean;
}

/**
 * 预加载配置映射
 */
export const DEFAULT_PRELOAD_CONFIGS: PreloadConfigItem[] = [
  {
    name: "easycom"
  },
  {
    name: "tabBar"
  }
];

/**
 * 预加载配置定义（可扩展）
 */
const PRELOAD_CONFIGS: PreloadConfigItem[] = [...DEFAULT_PRELOAD_CONFIGS];

/**
 * 配置预加载处理类
 */
export class ConfigPreloader {

  /**
   * 检查并处理启动时的配置预加载
   * @param configLoader 配置加载器
   * @param logger 日志记录器
   * @return 是否需要重启
   */
  public static async checkAndHandleOnStartup(configLoader: ConfigLoader, logger: Logger): Promise<boolean> {
    try {
      const currentConfig = configLoader.pages;
      let needsRestart = false;

      // 读取现有 pages.json 配置
      let existingConfig = null;
      if (fs.existsSync(configLoader.plugin.pagesJsonPath)) {
        const content = fs.readFileSync(configLoader.plugin.pagesJsonPath, 'utf-8');
        existingConfig = JSON.parse(content);
      }

      if (!existingConfig) existingConfig = {};

      // 检查每个需要预加载的配置
      for (const configItem of PRELOAD_CONFIGS) {
        const configValue = currentConfig[configItem.name];

        const isChanged = this.isConfigChanged(
          existingConfig[configItem.name],
          configValue,
          configItem.compareFunction
        );

        if (isChanged) {
          logger.info(`检测到 ${configItem.name} 配置变化`);
          existingConfig[configItem.name] = configValue;
          needsRestart = true;
        }
      }

      // 如果需要重启，写入文件
      if (needsRestart) {
        PagesJsonHelper.write(configLoader.plugin.pagesJsonPath, existingConfig);

        logger.info('检测到需要重启的配置变化，准备重启');
      }

      return needsRestart;
    } catch (error) {
      logger.warn(`配置预加载处理出错: ${error}`);
      return false;
    }
  }

  /**
   * 判断配置是否发生变化
   * @param oldConfig 旧配置
   * @param newConfig 新配置
   * @param compareFunction 自定义比较函数
   * @returns 是否发生变化
   */
  private static isConfigChanged(
    oldConfig: any,
    newConfig: any,
    compareFunction?: (oldConfig: any, newConfig: any) => boolean
  ): boolean {
    if (compareFunction) {
      return compareFunction(oldConfig, newConfig);
    }

    // 默认比较方法：JSON字符串比较
    return JSON.stringify(oldConfig) !== JSON.stringify(newConfig);
  }

  /**
   * 重启应用
   */
  public static async restart(): Promise<void> {
    const {spawn} = await import('node:child_process');

    return new Promise((resolve) => {
      const build = spawn(process.argv.shift()!, process.argv, {
        cwd: process.env.VITE_ROOT_DIR || process.cwd(),
        detached: true,
        env: process.env,
      });

      // 关键：管道输出，而不是使用 stdio: 'inherit'
      build.stdout?.pipe(process.stdout);
      build.stderr?.pipe(process.stderr);

      build.on('close', (code) => {
        resolve(process.exit(code!));
      });
    });
  }

  /**
   * 获取预加载配置列表（用于调试和扩展）
   */
  public static getPreloadConfigs(): PreloadConfigItem[] {
    return [...PRELOAD_CONFIGS];
  }

  /**
   * 添加自定义预加载配置
   * @param configItem 配置项
   */
  public static addPreloadConfig(configItem: PreloadConfigItem): void {
    // 检查是否已存在同名配置
    const existingIndex = PRELOAD_CONFIGS.findIndex(item => item.name === configItem.name);
    if (existingIndex !== -1) {
      // 更新现有配置
      PRELOAD_CONFIGS[existingIndex] = configItem;
    } else {
      // 添加新配置
      PRELOAD_CONFIGS.push(configItem);
    }
  }
}
